package com.getpebble.android.common.core.trace;

import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
import android.util.Log;
import com.getpebble.android.PebbleApplication;
import com.getpebble.android.R;
import com.getpebble.android.common.core.util.PblPreferences;
import com.getpebble.android.common.core.util.PblPreferences.PrefKey;
import com.getpebble.android.common.core.util.ProcessUtil;
import com.getpebble.android.common.core.util.ProcessUtil.PebbleProcess;
import com.sun.mail.imap.protocol.ListInfo;
import com.sun.mail.smtp.SMTPMessage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.text.SimpleDateFormat;
import java.util.Date;

public class AndroidLogger {
    private static final String TAG = AndroidLogger.class.getSimpleName();
    private static PebbleProcess sCurrentProcess;
    private static SimpleDateFormat sDateFormat;
    private static boolean sForceVerboseLogcat = false;
    private static FileLock sLock;
    private static FileChannel sLockChannel;
    private static File sLockFile;
    private static File sLogFile;
    private static Handler sLogHandler;
    private static PrintWriter sPrintWriter;
    private static int sWrittenLineCount = 0;

    static /* synthetic */ class AnonymousClass3 {
        static final /* synthetic */ int[] $SwitchMap$com$getpebble$android$common$core$trace$Trace$Level = new int[Level.values().length];
        static final /* synthetic */ int[] $SwitchMap$com$getpebble$android$common$core$util$ProcessUtil$PebbleProcess = new int[PebbleProcess.values().length];

        static {
            try {
                $SwitchMap$com$getpebble$android$common$core$trace$Trace$Level[Level.ASSERT.ordinal()] = 1;
            } catch (NoSuchFieldError e) {
            }
            try {
                $SwitchMap$com$getpebble$android$common$core$trace$Trace$Level[Level.WARNING.ordinal()] = 2;
            } catch (NoSuchFieldError e2) {
            }
            try {
                $SwitchMap$com$getpebble$android$common$core$trace$Trace$Level[Level.INFO.ordinal()] = 3;
            } catch (NoSuchFieldError e3) {
            }
            try {
                $SwitchMap$com$getpebble$android$common$core$trace$Trace$Level[Level.DEBUG.ordinal()] = 4;
            } catch (NoSuchFieldError e4) {
            }
            try {
                $SwitchMap$com$getpebble$android$common$core$trace$Trace$Level[Level.VERBOSE.ordinal()] = 5;
            } catch (NoSuchFieldError e5) {
            }
            try {
                $SwitchMap$com$getpebble$android$common$core$trace$Trace$Level[Level.ERROR.ordinal()] = 6;
            } catch (NoSuchFieldError e6) {
            }
            try {
                $SwitchMap$com$getpebble$android$common$core$util$ProcessUtil$PebbleProcess[PebbleProcess.UI.ordinal()] = 1;
            } catch (NoSuchFieldError e7) {
            }
            try {
                $SwitchMap$com$getpebble$android$common$core$util$ProcessUtil$PebbleProcess[PebbleProcess.FRAMEWORK.ordinal()] = 2;
            } catch (NoSuchFieldError e8) {
            }
        }
    }

    static {
        HandlerThread logThread = new HandlerThread("logging");
        logThread.start();
        sLogHandler = new Handler(logThread.getLooper());
    }

    public static String getLogFile(Context appContext, PebbleProcess process) {
        return appContext.getDir("logs", 0) + File.separator + "pebble_" + process + ".log";
    }

    public static void init(Context context, PebbleProcess currentProcess) {
        sCurrentProcess = currentProcess;
        sLogFile = new File(getLogFile(context, sCurrentProcess));
        sLockFile = new File(context.getDir("logs", 0) + File.separator + "log.sLock");
        sForceVerboseLogcat = new PblPreferences(context).getBooleanData(PrefKey.VERBOSE_LOGCAT, false);
        sLogHandler.post(new Runnable() {
            public void run() {
                AndroidLogger.initLogFile();
            }
        });
    }

    private static int getMaxLogFileSize() {
        switch (AnonymousClass3.$SwitchMap$com$getpebble$android$common$core$util$ProcessUtil$PebbleProcess[sCurrentProcess.ordinal()]) {
            case SMTPMessage.RETURN_FULL /*1*/:
                return 700000;
            case SMTPMessage.RETURN_HDRS /*2*/:
                return 1500000;
            default:
                throw new IllegalStateException("Max log file size requested for invalid process: " + sCurrentProcess);
        }
    }

    public static void setVerboseLogcat(boolean verbose) {
        sForceVerboseLogcat = verbose;
        if (PebbleProcess.FRAMEWORK.equals(ProcessUtil.getProcess(PebbleApplication.getAppContext()))) {
            new PblPreferences(PebbleApplication.getAppContext()).setBooleanData(PrefKey.VERBOSE_LOGCAT, verbose);
        } else {
            PebbleApplication.getFrameworkInterface().setVerboseLogcat(verbose);
        }
    }

    private static void initLogFile() {
        Trace.debug(TAG, "log file: " + sLogFile);
        if (sPrintWriter != null) {
            sPrintWriter.close();
        }
        if (sDateFormat == null) {
            sDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
        }
        try {
            sPrintWriter = new PrintWriter(new FileWriter(sLogFile, true));
        } catch (IOException e) {
            Log.e(TAG, "Error opening log file", e);
        }
    }

    private static String getTagString(Level level) {
        switch (AnonymousClass3.$SwitchMap$com$getpebble$android$common$core$trace$Trace$Level[level.ordinal()]) {
            case SMTPMessage.RETURN_FULL /*1*/:
                return "A";
            case SMTPMessage.RETURN_HDRS /*2*/:
                return "W";
            case ListInfo.INDETERMINATE /*3*/:
                return "I";
            case SMTPMessage.NOTIFY_DELAY /*4*/:
                return "D";
            case R.styleable.WalletFragmentStyle_maskedWalletDetailsHeaderTextAppearance /*5*/:
                return "V";
            default:
                return "E";
        }
    }

    private static void logToFile(Level level, String tag, String message, Throwable throwable, Date date, int process, int thread) {
        if (sPrintWriter != null) {
            String dateTime = sDateFormat.format(date);
            String stackTrace = "";
            if (throwable != null) {
                stackTrace = "\n" + Log.getStackTraceString(throwable);
            }
            sPrintWriter.println(dateTime + " " + process + " " + thread + " " + getTagString(level) + " " + tag + ": " + message + stackTrace);
            sPrintWriter.flush();
            int i = sWrittenLineCount + 1;
            sWrittenLineCount = i;
            if (i % 2000 == 0 && sLogFile.length() > ((long) getMaxLogFileSize())) {
                truncateFile();
            }
        }
    }

    private static void truncateFile() {
        IOException e;
        Throwable th;
        Trace.debug(TAG, "truncateFile()");
        if (acquireLogFileLock()) {
            sPrintWriter.close();
            File tmp = new File(sLogFile.getPath() + ".tmp");
            if (!tmp.exists() || tmp.delete()) {
                try {
                    if (sLogFile.renameTo(tmp)) {
                        int bytesToSkip = ((int) tmp.length()) - getMaxLogFileSize();
                        if (bytesToSkip <= 0) {
                            Trace.debug(TAG, "Not doing truncation; nothing to skip");
                            releaseLogFileLock();
                            return;
                        }
                        InputStream in = null;
                        OutputStream out = null;
                        try {
                            OutputStream out2;
                            InputStream in2 = new FileInputStream(tmp);
                            try {
                                out2 = new FileOutputStream(sLogFile, false);
                            } catch (IOException e2) {
                                e = e2;
                                in = in2;
                                try {
                                    Trace.debug(TAG, "Error truncating file", e);
                                    if (in != null) {
                                        try {
                                            in.close();
                                        } catch (IOException e3) {
                                            Trace.debug(TAG, "Error closing in", e3);
                                        }
                                    }
                                    if (out != null) {
                                        try {
                                            out.close();
                                        } catch (IOException e32) {
                                            Trace.debug(TAG, "Error closing out", e32);
                                        }
                                    }
                                    Trace.warning(TAG, "truncate: error deleting tmp file (after)");
                                    initLogFile();
                                    releaseLogFileLock();
                                    return;
                                } catch (Throwable th2) {
                                    th = th2;
                                    if (in != null) {
                                        try {
                                            in.close();
                                        } catch (IOException e322) {
                                            Trace.debug(TAG, "Error closing in", e322);
                                        }
                                    }
                                    if (out != null) {
                                        try {
                                            out.close();
                                        } catch (IOException e3222) {
                                            Trace.debug(TAG, "Error closing out", e3222);
                                        }
                                    }
                                    throw th;
                                }
                            } catch (Throwable th3) {
                                th = th3;
                                in = in2;
                                if (in != null) {
                                    in.close();
                                }
                                if (out != null) {
                                    out.close();
                                }
                                throw th;
                            }
                            try {
                                if (in2.skip((long) bytesToSkip) != ((long) bytesToSkip)) {
                                    Trace.info(TAG, "skipped != bytesToSkip");
                                }
                                int nextByte;
                                do {
                                    nextByte = in2.read();
                                    if (nextByte == 10) {
                                        break;
                                    }
                                } while (nextByte != -1);
                                byte[] buf = new byte[1024];
                                while (true) {
                                    int len = in2.read(buf);
                                    if (len <= 0) {
                                        break;
                                    }
                                    out2.write(buf, 0, len);
                                }
                                if (in2 != null) {
                                    in2.close();
                                }
                                if (out2 != null) {
                                    try {
                                        out2.close();
                                        out = out2;
                                        in = in2;
                                    } catch (IOException e32222) {
                                        Trace.debug(TAG, "Error closing out", e32222);
                                        out = out2;
                                        in = in2;
                                    }
                                } else {
                                    in = in2;
                                }
                            } catch (IOException e4) {
                                e32222 = e4;
                                out = out2;
                                in = in2;
                                Trace.debug(TAG, "Error truncating file", e32222);
                                if (in != null) {
                                    in.close();
                                }
                                if (out != null) {
                                    out.close();
                                }
                                Trace.warning(TAG, "truncate: error deleting tmp file (after)");
                                initLogFile();
                                releaseLogFileLock();
                                return;
                            } catch (Throwable th4) {
                                th = th4;
                                out = out2;
                                in = in2;
                                if (in != null) {
                                    in.close();
                                }
                                if (out != null) {
                                    out.close();
                                }
                                throw th;
                            }
                        } catch (IOException e5) {
                            e32222 = e5;
                            Trace.debug(TAG, "Error truncating file", e32222);
                            if (in != null) {
                                in.close();
                            }
                            if (out != null) {
                                out.close();
                            }
                            Trace.warning(TAG, "truncate: error deleting tmp file (after)");
                            initLogFile();
                            releaseLogFileLock();
                            return;
                        }
                        if (tmp.exists() && !tmp.delete()) {
                            Trace.warning(TAG, "truncate: error deleting tmp file (after)");
                        }
                        initLogFile();
                        releaseLogFileLock();
                        return;
                    }
                    Trace.warning(TAG, "truncate: error renaming log file");
                    releaseLogFileLock();
                    return;
                } catch (IOException e322222) {
                    Trace.debug(TAG, "Error closing in", e322222);
                } catch (Throwable th5) {
                    releaseLogFileLock();
                }
            } else {
                Trace.warning(TAG, "truncate: error deleting tmp file (before)");
                releaseLogFileLock();
                return;
            }
        }
        Trace.debug(TAG, "Could not acquire file lock; not truncating");
    }

    public static void log(Level level, String tag, String message, Throwable throwable) {
        if (message == null || message.length() < 1) {
            message = "No message provided!";
        }
        StringBuilder logMessage = new StringBuilder("[");
        logMessage.append(tag);
        logMessage.append("] ");
        logMessage.append(message);
        final String messageToSend = logMessage.toString();
        final Date date = new Date();
        switch (AnonymousClass3.$SwitchMap$com$getpebble$android$common$core$trace$Trace$Level[level.ordinal()]) {
            case SMTPMessage.RETURN_FULL /*1*/:
                Log.wtf("PebbleApplication", messageToSend, throwable);
                break;
            case SMTPMessage.RETURN_HDRS /*2*/:
                Log.w("PebbleApplication", messageToSend, throwable);
                break;
            case ListInfo.INDETERMINATE /*3*/:
                if (sForceVerboseLogcat) {
                    Log.i("PebbleApplication", messageToSend, throwable);
                    break;
                }
                break;
            case SMTPMessage.NOTIFY_DELAY /*4*/:
                if (sForceVerboseLogcat) {
                    Log.d("PebbleApplication", messageToSend, throwable);
                    break;
                }
                break;
            case R.styleable.WalletFragmentStyle_maskedWalletDetailsHeaderTextAppearance /*5*/:
                if (sForceVerboseLogcat) {
                    Log.v("PebbleApplication", messageToSend, throwable);
                    break;
                }
                break;
            default:
                Log.e("PebbleApplication", messageToSend, throwable);
                break;
        }
        final int process = Process.myPid();
        final int thread = Process.myTid();
        final Level level2 = level;
        final Throwable th = throwable;
        sLogHandler.post(new Runnable() {
            public void run() {
                AndroidLogger.logToFile(level2, "PebbleApplication", messageToSend, th, date, process, thread);
            }
        });
    }

    public static boolean acquireLogFileLock() {
        Trace.debug(TAG, "acquireLogFileLock()");
        try {
            sLockChannel = new RandomAccessFile(sLockFile, "rw").getChannel();
            sLock = sLockChannel.lock();
            return true;
        } catch (FileNotFoundException e) {
            Trace.debug(TAG, "acquireLogFileLock", e);
            if (sLock != null) {
                try {
                    sLock.release();
                } catch (IOException e2) {
                    Trace.debug(TAG, "Error releasing sLock", e2);
                }
                sLock = null;
            }
            if (sLockChannel != null) {
                try {
                    sLockChannel.close();
                } catch (IOException e22) {
                    Trace.debug(TAG, "Error closing sLockChannel", e22);
                }
                sLockChannel = null;
            }
            return false;
        } catch (IOException e222) {
            Trace.debug(TAG, "acquireLogFileLock", e222);
            if (sLock != null) {
                sLock.release();
                sLock = null;
            }
            if (sLockChannel != null) {
                sLockChannel.close();
                sLockChannel = null;
            }
            return false;
        }
    }

    public static void releaseLogFileLock() {
        Trace.debug(TAG, "releaseLogFileLock()");
        if (sLock == null) {
            Trace.debug(TAG, "releaseLogFileLock: no sLock held");
            return;
        }
        try {
            sLock.release();
        } catch (IOException e) {
            Trace.debug(TAG, "Error releasing sLock", e);
        }
        sLock = null;
        if (sLockChannel != null) {
            try {
                sLockChannel.close();
            } catch (IOException e2) {
                Trace.debug(TAG, "Error closing sLockChannel", e2);
            }
            sLockChannel = null;
        }
    }
}
